/*
 * Client.c
 *
 *  Created on: Nov 25, 2013
 *      Author: SAGUET Julien et POCREAU Aymeric
 */

#include "../includes/client.h"
#include "../includes/common.h"

#define MAXBUF 1024
#define PORT 33000
#define PANIC(msg) {perror("msg");exit(EXIT_FAILURE);}

int main(int argc, char *argv[]) {

	fd_set readfds;
	int socketEcoute;
	int n;
	char *ip;
	int max = 0;
	char *endptr;
	int port;
	char *buffer = malloc(sizeof(char) * MAXBUF);
	int fd[4] = { -1 };
	struct stat info;
	int ret = 1;
	FILE* filedesc;
	char* buff;
	char c;
	int size;
	int port_file = 0;
	int file;
	struct sockaddr_in addr;
	FILE* filefd;
	char* ligne;
	int conn_s;

	// Usage
	if (argc == 3) {
		port = strtol(argv[2], &endptr, 0);
		ip = argv[1];
		if (*endptr) {
			fprintf(stderr, "ECHOSERV : Invalid port number\n");
			exit(EXIT_FAILURE);
		}
	} else if (argc < 3) {
		port = PORT;
		ip = "127.0.0.1";
	} else {
		fprintf(stderr, "ECHOSERV: Invalid arguments\n");
		exit(EXIT_FAILURE);
	}
	fd[0] = STDIN_FILENO;

	// Création d'une socket d'écoute
	socketEcoute = create_socket(ip, port);
	fd[1] = socketEcoute;
	int i = 0;

	while (1) {

		FD_ZERO(&readfds);

		// On remplit tous les descripteurs de fichiers
		for (i = 0; i <= 3; i++) {
			if (fd[i] != -1) {
				FD_SET(fd[i], &readfds);
				if (fd[i] > max) {
					max = fd[i];
				}
			}
		}

		if (select(max + 1, &readfds, NULL, NULL, NULL) == -1) {
			perror("select");
			exit(EXIT_FAILURE);
		}

		// Informations via le clavier
		if (FD_ISSET(STDIN_FILENO, &readfds)) {
			memset(buffer, 0, MAXBUF);
			buffer = fgets(buffer, MAXBUF, stdin);
			clean(buffer);

			// Envoie de la saisie au serveur
			if (sendline(socketEcoute, buffer, strlen(buffer)) < 0)
				PANIC(sendline);

			// Envoie de fichier
			if (!strncmp(buffer, ".request", 8)) {

				// Reception de la structure sockaddr_in
				read(socketEcoute, &addr, sizeof(addr));
				fprintf(stdout, "Port reçu au bout : %d\n",
						ntohs(addr.sin_port));
				fprintf(stdout, "ip : %s\n", inet_ntoa(addr.sin_addr));

				// Creation de la socket pour l'envoi de fichiers
				fd[2] = create_socket(inet_ntoa(addr.sin_addr),
						ntohs(addr.sin_port));
				fprintf(stdout, "Victory !\n");

				// Lecture du nombre de caractères
				file = open("testfile", O_RDONLY);
				fstat(file, &info);
				fprintf(stdout, "taille fichier : %d\n", (int) info.st_size);
				ligne = malloc(sizeof(char) * info.st_size - 1);
				filefd = fopen("testfile", "r");

				// Envoie  du nombre de caractères
				write(fd[2], &info.st_size, sizeof(int));
				fgets(ligne, info.st_size, filefd);

				// Envoie du contenu du fichier
				for (i = 0; i < info.st_size - 1; i++) {
					fprintf(stdout, "ligne[%d] : %c\n", i, ligne[i]);
					if (write(fd[2], &(ligne[i]), 1) < 0) {
						perror("write");
						exit(EXIT_FAILURE);
					}
				}
				fprintf(stdout, "Fichier envoyé en entier\n");
			}

		} else if (FD_ISSET(socketEcoute, &readfds)) {
			memset(buffer, 0, MAXBUF);
			n = readline(socketEcoute, buffer, MAXBUF - 1);

			// Serveur déconnecté
			if (n == 0) {
				printf("Server disconnected !\n");
				break;
			}
			if (!strcmp(buffer, ".request")) {
				fd[3] = create_socket_file(&port_file);
				fprintf(stdout, "Port : %d\n", port_file);
				write(socketEcoute, &port_file, sizeof(int));
			} else
				puts(buffer);

			// Connexion depuis un autre client
		} else if (FD_ISSET(fd[3], &readfds)) {
			fprintf(stdout, "demande de connexion recue !\n");
			if ((conn_s = accept(fd[3], NULL, NULL)) < 0) {
				perror("accept");
				exit(EXIT_FAILURE);
			}
			fprintf(stdout, "connexion recue par un tiers.\n");

			// Ouverture du fichier testfile2
			filedesc = fopen("testfile2", "r+");
			read(conn_s, &size, sizeof(int));
			buff = malloc(sizeof(char) * size);

			// Ecriture dans le fichier
			for (i = 0; i < size - 1; i++) {
				ret = read(conn_s, &c, 1);
				fprintf(stdout, " %d : %c\n", i, c);
				buff[i] = c;
			}
			buff[4] = '\0';
			fprintf(stdout, "%s\n", buff);

			fprintf(filedesc, "%s", buff);
			fflush(filedesc);
		}
	}
	return EXIT_SUCCESS;
}
